// AboutDlg.cpp : implementation of the CDraftsDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif
#include "sendstatusdlg.h"
#include "utils.h"
#include "DraftsDb.h"
#include "GroupsDb.h"
#include "DraftsDlg.h"
#include "GroupsDlg.h"
#include "MapiSms.h"
#include "SendInfoDlg.h"

LRESULT CSendStatusDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    m_Sent = false;

    AtlCreateMenuBar(m_hWnd, IDM_MENU_SEND);

#ifdef WIN32_PLATFORM_WFSP
    if (hMenuBar != NULL)
        AtlActivateBackKey(hMenuBar);
#endif

    BOOL Ret = m_ImageList.Create(24, 24, ILC_COLORDDB | ILC_MASK, 2, 0);
    ATLASSERT(Ret == TRUE);

    CIcon icon;
    icon.LoadIcon(IDI_MEMBER, 24, 24);
    int Result = m_ImageList.AddIcon(icon);
    ATLASSERT(Result != -1);
    icon.DestroyIcon();

    m_List.Attach(GetDlgItem(IDC_LIST));
    m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
    m_List.SetImageList(m_ImageList, LVSIL_SMALL);

    CRect r;
    m_List.GetClientRect(&r);
    m_List.InsertColumn(COLUMN_CONTACT, NULL, LVCFMT_LEFT, r.Width());
    m_List.InsertColumn(COLUMN_STATUS, NULL, LVCFMT_RIGHT, r.Width());

    m_MessageEdt.Attach(GetDlgItem(IDC_EDT_MESSAGE));
    m_MessageEdt.LimitText(MAX_DRAFT);
    m_MessageEdt.SetWindowText(GetDraftFromId(CDraftsDb::FIRST_RECORD_ID));

    PopulateList();
    UpdateUI();

    return bHandled = FALSE;
}

LRESULT CSendStatusDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    CString Message;
    m_MessageEdt.GetWindowText(Message);
    SaveDraft(Message);

    m_MessageEdt.Detach();
    m_List.Detach();

    return bHandled = FALSE;
}

LRESULT CSendStatusDlg::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    OnSize();
    return bHandled = FALSE;
}

void CSendStatusDlg::OnSize(void)
{
    CRect r;
    m_List.GetClientRect(&r);
    m_List.SetColumnWidth(COLUMN_CONTACT, (int)(r.Width() * 0.70));
    m_List.SetColumnWidth(COLUMN_STATUS, (int)(r.Width() * 0.30));
}

void CSendStatusDlg::AddMember(UINT MemberId, CString &Name)
{
    LVITEM Item = { 0 };
    Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    Item.iItem = m_List.GetItemCount();
    Item.iSubItem = 0;
    Item.pszText = (LPTSTR)((LPCTSTR)Name);
    Item.iImage = 0;
    Item.lParam = MemberId;

    int NewIndex = m_List.InsertItem(&Item);
    if (NewIndex >= 0)
    {
        m_List.SelectItem(NewIndex);
        m_List.EnsureVisible(NewIndex, FALSE);
        m_List.SetFocus();
    }

    UpdateUI();
    OnSize();
}

LRESULT CSendStatusDlg::OnMenuStart(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    bool DeliveryNotification = false;

    int ret = Utils::MessageBoxRes(
        m_hWnd,
        IDR_MAINFRAME,
        IDS_CONFIRM_SEND,
        MB_ICONEXCLAMATION | MB_YESNOCANCEL | MB_DEFBUTTON3);
    if (ret == IDCANCEL)
        return 0;

    if (ret == IDYES)
        DeliveryNotification = true;

    m_Sent = true;
    UpdateUI();

    CString SendingStr;
    SendingStr.LoadString(IDS_SENDING);

    CString SendDoneStr;
    SendDoneStr.LoadString(IDS_SEND_DONE);

    CString SendFailedStr;
    SendFailedStr.LoadString(IDS_SEND_FAILED);

    CString Draft;
    m_MessageEdt.GetWindowText(Draft);
    SaveDraft(Draft);

    CString Message;
    CDraftsDb DraftsDb;
    DWORD Err = DraftsDb.Open();
    if (Err != ERROR_SUCCESS)
        return 0;

    Err = DraftsDb.GetFromId(CDraftsDb::FIRST_RECORD_ID, &Message, NULL);
    DraftsDb.Close();

    if (Err != ERROR_SUCCESS)
        return 0;

    CMembersDb MembersDb;
    MembersDb.Open();

    CMapiSms m_MapiSms;
    m_MapiSms.SetRecepientCount(m_List.GetItemCount());

    HRESULT hr = S_OK;

    for (int i = 0; i < m_List.GetItemCount(); i++)
    {
        m_List.SetItemText(i, COLUMN_STATUS, SendingStr);
        m_List.SelectItem(i);
        m_List.EnsureVisible(i, FALSE);

        LVITEM Item = {0};
        Item.mask = LVIF_PARAM;
        Item.iItem = i;
        Item.iSubItem = 0;
        BOOL ret = m_List.GetItem(&Item);
        if (ret == false)
        {
            m_List.SetItemText(i, COLUMN_STATUS, SendFailedStr);
            continue;
        }

        UINT MemberId = (UINT)Item.lParam;
        CEOID ContactId = 0;
        CEPROPID PropId = 0;
        Err = MembersDb.GetFromId(
            MemberId,
            NULL,
            &ContactId,
            &PropId,
            NULL);
        if (Err != ERROR_SUCCESS)
        {
            m_List.SetItemText(i, COLUMN_STATUS, SendFailedStr);
            continue;
        }

        CString Name;
        CString Number;
        HRESULT hr = Utils::GetContactDetails(
            ContactId,
            PropId,
            &Name,
            &Number);
        if (FAILED(hr))
        {
            m_List.SetItemText(i, COLUMN_STATUS, SendFailedStr);
            continue;
        }

        hr = m_MapiSms.AddRecepient(Name, Number);
        if (FAILED(hr))
        {
            m_List.SetItemText(i, COLUMN_STATUS, SendFailedStr);
            continue;
        }

        m_List.SetItemText(i, COLUMN_STATUS, SendDoneStr);
    }

    MembersDb.Close();

    hr = m_MapiSms.Send(Message, DeliveryNotification);
    if (SUCCEEDED(hr))
    {
        SHELLEXECUTEINFO sei = {0};
        sei.lpFile = _T("tmail.exe");
        sei.lpVerb = _T("Open");
        ShellExecuteEx(&sei);
    }

    m_MapiSms.ClearRecepients();

    CSendInfoDlg dlg;
    dlg.DoModal();

    StdCloseDialog(IDOK);
    return 0;
}

LRESULT CSendStatusDlg::OnMenuDrafts(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    CDraftsDlg dlg;
    dlg.SetSelectMode();
    int ret = dlg.DoModal();
    if (ret == IDOK)
    {
        DWORD DraftId = dlg.GetDraftId();
        CString Draft = GetDraftFromId(DraftId);
        SaveDraft(Draft);
        m_MessageEdt.SetWindowText(Draft);
    }

    return 0;
}

LRESULT CSendStatusDlg::OnMenuAddContact(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    CString Name;
    CString Number;
    CEOID ContactId = 0;
    CEPROPID PropertyId = 0;
    HRESULT hr = Utils::ChooseContact(
        m_hWnd,
        &Name,
        &Number,
        &ContactId,
        &PropertyId);
    if (FAILED(hr))
    {
        ATLTRACE(_T("Utils::ChooseContact failed\n"));
        return 0;
    }

    CMembersDb MembersDb;
    DWORD Err = MembersDb.Open();
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Members Db open failed\n"));
        return 0;
    }

    UINT MemberId = 0;
    Err = MembersDb.Add(
        CGroupsDb::FIRST_RECORD_ID,
        ContactId,
        PropertyId,
        &MemberId);
    MembersDb.Close();
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Add to members db failed\n"));
        return 0;
    }

    AddMember(MemberId, Name);
    return 0;
}

LRESULT CSendStatusDlg::OnMenuAddFromGroup(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    CGroupsDlg dlg;
    dlg.SetSelectMode();
    int ret = dlg.DoModal();
    if (ret == IDOK)
    {
        CMembersDb MembersDb;
        DWORD Err = MembersDb.Open();
        if (Err == ERROR_SUCCESS)
        {
            MembersDb.CopyFromId(
                CGroupsDb::FIRST_RECORD_ID,
                dlg.GetSelectedGroupId());
            MembersDb.Close();

            m_List.DeleteAllItems();
            PopulateList();
        }
    }

    return 0;
}

LRESULT CSendStatusDlg::OnMenuClearMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    SaveDraft(CString(_T("")));
    m_MessageEdt.SetWindowText(_T(""));
    UpdateUI();

    return 0;
}

LRESULT CSendStatusDlg::OnMenuClearRecepients(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    int ret = Utils::MessageBoxRes(
        m_hWnd,
        IDR_MAINFRAME,
        IDS_CONFIRM_CLEAR,
        MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2);
    if (ret == IDNO)
        return 0;

    CMembersDb MembersDb;
    DWORD Err = MembersDb.Open();
    if (Err == ERROR_SUCCESS)
    {
        MembersDb.DeleteByGroupId(CGroupsDb::FIRST_RECORD_ID);
        MembersDb.Close();

        m_List.DeleteAllItems();
        OnSize();
    }

    return 0;
}

LRESULT CSendStatusDlg::OnMenuDeleteRecepient(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    if (Ret == FALSE)
    {
        ATLTRACE(_T("No item selected to delete\n"));
        return 0;
    }

    CMembersDb MembersDb;
    DWORD Err = MembersDb.Open();
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to open db\n"));
        return 0;
    }

    UINT DbIndex = 0;
    Err = MembersDb.GetFromId(
        Item.lParam,
        NULL,
        NULL,
        NULL,
        &DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to get db index\n"));
        MembersDb.Close();
        return 0;
    }

    Err = MembersDb.Delete(DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to delete from db\n"));
        MembersDb.Close();
        return 0;
    }

    m_List.DeleteItem(Item.iItem);

    int ItemCount = m_List.GetItemCount();
    if (ItemCount > 0)
    {
        if (Item.iItem >= ItemCount)
            Item.iItem--;

        m_List.SelectItem(Item.iItem);
    }

    UpdateUI();
    OnSize();

    return 0;
}

CString CSendStatusDlg::GetDraftFromId(DWORD Id)
{
    CString Message;
    CDraftsDb DraftsDb;
    DWORD Err = DraftsDb.Open();
    if (Err == ERROR_SUCCESS)
    {
        Err = DraftsDb.GetFromId(Id, &Message, NULL);
        DraftsDb.Close();
    }

    return Message;
}

DWORD CSendStatusDlg::SaveDraft(CString &Draft)
{
    CDraftsDb DraftsDb;
    DWORD Err = DraftsDb.Open();
    if (Err == ERROR_SUCCESS)
    {
        UINT Index = 0;
        Err = DraftsDb.GetFromId(CDraftsDb::FIRST_RECORD_ID, NULL, &Index);
        if (Err == ERROR_SUCCESS)
            Err = DraftsDb.Set(Index, Draft);

        DraftsDb.Close();
    }

    return Err;
}

void CSendStatusDlg::PopulateList(void)
{
    CMembersDb MembersDb;
    MembersDb.Open();

    UINT i = 0;
    UINT Id = 0;
    UINT GroupId = 0;
    CEOID ContactId = 0;
    CEPROPID PropId = 0;
    DWORD Err = MembersDb.Get(i, &Id, &GroupId, &ContactId, &PropId);
    while (Err == ERROR_SUCCESS)
    {
        CString Name;
        HRESULT hr = Utils::GetContactDetails(ContactId, PropId, &Name, NULL);
        if (SUCCEEDED(hr))
        {
            i++;

            if (GroupId == CGroupsDb::FIRST_RECORD_ID)
                AddMember(Id, Name);
        }
        else
            MembersDb.Delete(i);

        Err = MembersDb.Get(i, &Id, &GroupId, &ContactId, &PropId);
    }

    MembersDb.Close();
}

void CSendStatusDlg::UpdateUI(void)
{
    bool Enable = m_MessageEdt.GetWindowTextLength() > 0 &&
        m_List.GetItemCount() > 0 &&
        m_Sent == false;

    Utils::EnableMenuItem(
        this->m_hWnd,
        ID_MENU_SEND,
        Enable);
}

LRESULT CSendStatusDlg::OnEdtMessageChange(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    UpdateUI();
    return 0;
}
